//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<ShellConsole.h>
///	@path	~/src/appear/xwin/
///	@date	2007/12/11
///	@desc	Shell-like script console.

#pragma once

#include "xeres.h"

#include "lib/math/rect.h"
#include "lib/utilities/dict.h"

#include "object/IScriptInterpreter.h"
#include "object/CVar.h"

#include "graphics/IFont.h"
#include "graphics/IGeometry.h"
#include "graphics/canvas/CCanvas.h"
#include "graphics/canvas/CCanvasText.h"
#include "graphics/canvas/CCanvasRollingText.h"
#include "graphics/common/common_vertex_decl.h"
#include "graphics/common/TQuadList.h"

#include "gui/composite/CCompositeTexture.h"

#include "appear/app/key_map.h"
#include "appear/app/console.h"
#include "appear/ctrl/ctrl_edit.h"

namespace xeres {

	/*!
		\class	ShellConsole
		\brief	Shell-like script console.
	*/
	class ShellConsole : public Console
	{
	public:

		/// \ctor
		ShellConsole( void );

		/// \dtor
		virtual ~ShellConsole( void );

	public:

	//@ interface

		/*!
			\brief		Initialize shell console.
		*/
		bool Initialize( Engine& engine );

		/*!
			\brief		Finalize shell console.
		*/
		virtual void Finalize( void );

		/*!
			\brief		Tick update call.
		*/
		virtual void Tick( Engine& engine );

		/*!
			\brief		Render console.
		*/
		virtual void Render( RenderContext& rc );

		/*!
			\brief		Process key input message.
		*/
		virtual HandleInput OnKeyInput( const KeyInput& input );

		/*!
			\brief		Process mouse input message.
		*/
		virtual HandleInput OnMouseInput( const MouseInput& input );

		/*!
			\brief		Callback when active or deactive.
		*/
		virtual void OnActive( bool is_active );

		/*!
			\brief		Add new interpreter.
		*/
		bool AddInterpreter( const WString& name ,
			RefWeak<IScriptInterpreter> interp );

		/*! 
			\brief		Active interpreter.
		*/
		void ActiveInterpreter( const WString& interpreter );

		/*!	
			\brief		Get active interpreter.
		*/
		const WString& GetActiveInterpreter( void ) const;

	protected:

		/*!
			\brief		Execute command.
		*/
		virtual void OnExecute( void );

	private:

		/*!
			\brief		Add trace string.
		*/
		void TraceString( TraceLevel level , const wchar_t * msg );

		// prepare console resources
		void PrepareConsoleResource( RenderContext& rc );

		// prepare overlay
		void PrepareOverlay( RenderContext& rc , const Rect<int>& rect ,
			int split , const Rect<int>& input );

	//@ data

		// status
		bool					m_actived;
		bool					m_reset;
		bool					m_histroySelected;
		bool					m_spare0;

		// for trace call hook
		int						m_traceCallId;

		// edit height
		int						m_editHeight;

		// console rectangle
		Rect<int>				m_rect;
		Rect<int>				m_editRect;

		// canvas of console to draw
		// debug canvas screen
		Ref<CCanvas>			m_canvas;
		Ref<CCanvasRollingText>	m_traceText;
		Ref<CCanvasRollingText>	m_shellText;

		TQuadList<vd::ScreenColor,2>	m_quads;
		Ref<IVertexLayout>				m_quadLayout;
		TQuadList<vd::ScreenTexture,1>	m_editQuad;
		Ref<IVertexLayout>				m_editLayout;
		Ref<IShaderAdapter>				m_editAdapter;
		Ref<IShader>					m_editShader;
		Ref<IShaderVariable>			m_editVar;

		Ref<IFont>				m_interpNameFont;
		Ref<CVar>				m_interpName;
		Ref<CCanvasText>		m_interpNameText;

		Ref<CVar>				m_prompt;
		Ref<CCanvasText>		m_promptText;
		Ref<CCompositeTexture>	m_layerTexture;

		// debug trace font
		Ref<IFont>				m_traceFont;

		// edit control
		CtrlEdit				m_edit;

		// interpreter
		dict<WString , Ref<IScriptInterpreter> > m_interps;
		RefWeak<IScriptInterpreter>		m_currentInterp;
		WString					m_interpreterName;

		// history
		std::vector<WString>	m_history;
		int						m_histroyIndex;
		int						m_historyCurrent;
		size_t					m_historyMax;

		// short cut map
		KeyMap					m_hotkey;

		// last cue
		WString					m_cue;
	};

} // namespace xeres
